iT邦幫忙

2024 iThome 鐵人賽

DAY 14
0

今天是第14天最近地震頻繁因此我們可以寫一個yolo辨識氣候變遷的程式,以下是程式碼

import cv2
import numpy as np
import time
from ultralytics import YOLO
from collections import defaultdict

# 載入YOLOv8模型
model = YOLO('yolov8n.pt')

# 設定自訂的標籤
model.names = {0: 'flood', 1: 'wildfire'}

# 影片輸入路徑與輸出路徑
input_video = 'climate_change_video.mp4'
output_video = 'annotated_output.mp4'

# 設定視頻輸出參數
cap = cv2.VideoCapture(input_video)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
out = cv2.VideoWriter(output_video, cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))

# 計算場景中各類物體佔比
def calculate_object_proportion(results, frame_area):
    object_areas = defaultdict(int)
    for r in results:
        for box in r.boxes:
            label = model.names[int(box.cls)]
            x1, y1, x2, y2 = map(int, box.xyxy)
            object_area = (x2 - x1) * (y2 - y1)
            object_areas[label] += object_area

    proportions = {label: area / frame_area for label, area in object_areas.items()}
    return proportions

# 發送警報函數
def send_alert(detection_type):
    # 這裡可以加入發送電子郵件或通知的邏輯
    print(f"警報:偵測到 {detection_type}!")

# 處理每一幀影片
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_area = frame.shape[0] * frame.shape[1]
    start_time = time.time()

    results = model(frame)

    # 在影像上繪製偵測結果
    annotated_frame = results[0].plot()

    # 計算並顯示佔比
    proportions = calculate_object_proportion(results, frame_area)
    for label, prop in proportions.items():
        cv2.putText(annotated_frame, f"{label}: {prop*100:.2f}%", (10, 30 + 30*list(proportions.keys()).index(label)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)

    # 發送警報(如果檢測到洪水或火災)
    for label in proportions.keys():
        if label in ['flood', 'wildfire']:
            send_alert(label)

    # 儲存每一幀到影片
    out.write(annotated_frame)

    # 顯示影像
    cv2.imshow('YOLOv8 - Climate Change Detection', annotated_frame)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    print(f"Processed frame in {time.time() - start_time:.2f} seconds")

# 釋放資源
cap.release()
out.release()
cv2.destroyAllWindows()

1. 載入庫和模型

import cv2
import numpy as np
import time
from ultralytics import YOLO
from collections import defaultdict
  • cv2:OpenCV,用於影像處理和顯示。
  • numpy:數值計算庫,這裡用於處理數據。
  • time:用於計算處理時間。
  • YOLO:從Ultralytics庫載入YOLO模型。
  • defaultdict:用於計算每種類別的物體面積。

2. 載入YOLO模型

model = YOLO('yolov8n.pt')
model.names = {0: 'flood', 1: 'wildfire'}
  • YOLO('yolov8n.pt'):載入預訓練的YOLOv8模型。yolov8n.pt是YOLOv8的輕量版本模型檔案。
  • model.names:設定模型的標籤,這裡我們假設模型已經經過微調,能夠識別“flood”(洪水)和“wildfire”(森林火災)。

3. 影片輸入和輸出設定

input_video = 'climate_change_video.mp4'
output_video = 'annotated_output.mp4'

cap = cv2.VideoCapture(input_video)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
out = cv2.VideoWriter(output_video, cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))
  • cv2.VideoCapture(input_video):開啟輸入影片。
  • frame_width, frame_height, fps:獲取影片的寬度、高度和幀率。
  • cv2.VideoWriter(output_video, ...):設定輸出影片的寫入參數,將處理後的幀寫入新影片。

4. 計算物體佔比

def calculate_object_proportion(results, frame_area):
    object_areas = defaultdict(int)
    for r in results:
        for box in r.boxes:
            label = model.names[int(box.cls)]
            x1, y1, x2, y2 = map(int, box.xyxy)
            object_area = (x2 - x1) * (y2 - y1)
            object_areas[label] += object_area

    proportions = {label: area / frame_area for label, area in object_areas.items()}
    return proportions
  • calculate_object_proportion:計算每種類別物體在影像中的佔比。
  • results:YOLO模型的檢測結果。
  • frame_area:影像的總面積。
  • object_areas:記錄每種類別的物體總面積。
  • proportions:計算每種類別物體的佔比。

5. 發送警報

def send_alert(detection_type):
    # 這裡可以加入發送電子郵件或通知的邏輯
    print(f"警報:偵測到 {detection_type}!")
  • send_alert:當偵測到特定的物體(如洪水或森林火災)時,發送警報。
  • print:這裡僅是示範,可以擴展為實際的通知系統。

6. 處理每一幀影片

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_area = frame.shape[0] * frame.shape[1]
    start_time = time.time()

    results = model(frame)

    # 在影像上繪製偵測結果
    annotated_frame = results[0].plot()

    # 計算並顯示佔比
    proportions = calculate_object_proportion(results, frame_area)
    for label, prop in proportions.items():
        cv2.putText(annotated_frame, f"{label}: {prop*100:.2f}%", (10, 30 + 30*list(proportions.keys()).index(label)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)

    # 發送警報(如果檢測到洪水或火災)
    for label in proportions.keys():
        if label in ['flood', 'wildfire']:
            send_alert(label)

    # 儲存每一幀到影片
    out.write(annotated_frame)

    # 顯示影像
    cv2.imshow('YOLOv8 - Climate Change Detection', annotated_frame)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    print(f"Processed frame in {time.time() - start_time:.2f} seconds")
  • while cap.isOpened():持續處理影片的每一幀。
  • frame_area:計算影像面積。
  • results = model(frame):使用YOLO模型檢測當前幀中的物體。
  • annotated_frame = results[0].plot():在影像上繪製檢測結果。
  • calculate_object_proportion(results, frame_area):計算每種類別物體的佔比並顯示在影像上。
  • send_alert(label):如果檢測到關心的物體(洪水或森林火災),發送警報。
  • out.write(annotated_frame):將處理過的幀寫入輸出影片。
  • cv2.imshow('YOLOv8 - Climate Change Detection', annotated_frame):顯示當前幀。
  • cv2.waitKey(1) & 0xFF == ord('q'):按下‘q’鍵退出。

7. 釋放資源

cap.release()
out.release()
cv2.destroyAllWindows()
  • cap.release():釋放視頻捕捉對象。
  • out.release():釋放視頻寫入對象。
  • cv2.destroyAllWindows():關閉所有OpenCV窗口。

這個腳本展示了如何使用YOLOv8模型來偵測和分析氣候變遷相關的影像資料,並將結果處理成影片,進行實時顯示和警報。我可以更進一步擴展功能,例如更高級的分析、不同的警報方式或整合到更大規模的系統中。

1. 載入庫和模型

import cv2
import numpy as np
import time
from ultralytics import YOLO
from collections import defaultdict
  • cv2:OpenCV,用於影像處理和顯示。
  • numpy:數值計算庫,這裡用於處理數據。
  • time:用於計算處理時間。
  • YOLO:從Ultralytics庫載入YOLO模型。
  • defaultdict:用於計算每種類別的物體面積。

2. 載入YOLO模型

model = YOLO('yolov8n.pt')
model.names = {0: 'flood', 1: 'wildfire'}
  • YOLO('yolov8n.pt'):載入預訓練的YOLOv8模型。yolov8n.pt是YOLOv8的輕量版本模型檔案。
  • model.names:設定模型的標籤,這裡我們假設模型已經經過微調,能夠識別“flood”(洪水)和“wildfire”(森林火災)。

3. 影片輸入和輸出設定

input_video = 'climate_change_video.mp4'
output_video = 'annotated_output.mp4'

cap = cv2.VideoCapture(input_video)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
out = cv2.VideoWriter(output_video, cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))
  • cv2.VideoCapture(input_video):開啟輸入影片。
  • frame_width, frame_height, fps:獲取影片的寬度、高度和幀率。
  • cv2.VideoWriter(output_video, ...):設定輸出影片的寫入參數,將處理後的幀寫入新影片。

4. 計算物體佔比

def calculate_object_proportion(results, frame_area):
    object_areas = defaultdict(int)
    for r in results:
        for box in r.boxes:
            label = model.names[int(box.cls)]
            x1, y1, x2, y2 = map(int, box.xyxy)
            object_area = (x2 - x1) * (y2 - y1)
            object_areas[label] += object_area

    proportions = {label: area / frame_area for label, area in object_areas.items()}
    return proportions
  • calculate_object_proportion:計算每種類別物體在影像中的佔比。
  • results:YOLO模型的檢測結果。
  • frame_area:影像的總面積。
  • object_areas:記錄每種類別的物體總面積。
  • proportions:計算每種類別物體的佔比。

5. 發送警報

def send_alert(detection_type):
    # 這裡可以加入發送電子郵件或通知的邏輯
    print(f"警報:偵測到 {detection_type}!")
  • send_alert:當偵測到特定的物體(如洪水或森林火災)時,發送警報。
  • print:這裡僅是示範,可以擴展為實際的通知系統。

6. 處理每一幀影片

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    
    frame_area = frame.shape[0] * frame.shape[1]
    start_time = time.time()

    results = model(frame)

    # 在影像上繪製偵測結果
    annotated_frame = results[0].plot()

    # 計算並顯示佔比
    proportions = calculate_object_proportion(results, frame_area)
    for label, prop in proportions.items():
        cv2.putText(annotated_frame, f"{label}: {prop*100:.2f}%", (10, 30 + 30*list(proportions.keys()).index(label)), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)

    # 發送警報(如果檢測到洪水或火災)
    for label in proportions.keys():
        if label in ['flood', 'wildfire']:
            send_alert(label)

    # 儲存每一幀到影片
    out.write(annotated_frame)

    # 顯示影像
    cv2.imshow('YOLOv8 - Climate Change Detection', annotated_frame)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    print(f"Processed frame in {time.time() - start_time:.2f} seconds")
  • while cap.isOpened():持續處理影片的每一幀。
  • frame_area:計算影像面積。
  • results = model(frame):使用YOLO模型檢測當前幀中的物體。
  • annotated_frame = results[0].plot():在影像上繪製檢測結果。
  • calculate_object_proportion(results, frame_area):計算每種類別物體的佔比並顯示在影像上。
  • send_alert(label):如果檢測到關心的物體(洪水或森林火災),發送警報。
  • out.write(annotated_frame):將處理過的幀寫入輸出影片。
  • cv2.imshow('YOLOv8 - Climate Change Detection', annotated_frame):顯示當前幀。
  • cv2.waitKey(1) & 0xFF == ord('q'):按下‘q’鍵退出。

7. 釋放資源

cap.release()
out.release()
cv2.destroyAllWindows()
  • cap.release():釋放視頻捕捉對象。
  • out.release():釋放視頻寫入對象。
  • cv2.destroyAllWindows():關閉所有OpenCV窗口。

這個腳本展示了如何使用YOLOv8進行即時氣候變遷影像的偵測,例如洪水和森林火災。它能在影像上標註檢測到的物體,計算每種物體的佔比,並發出警報。這種系統可以幫助我們更好地理解和應對氣候變遷的影響。


上一篇
Day 13 yolo四隻斑馬魚辨識行為
下一篇
day 15 Lstm 結合yolo 多隻斑馬魚使用介面
系列文
基於人工智慧與深度學習對斑馬魚做行為分析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言